#!/usr/bin/python
#coding:utf-8
import ConfigParser
import os
import threading
import json

configDir  = "./"
configPath = "C:\\config.ini"

configMutex = threading.Lock()

class MyConf(ConfigParser.ConfigParser):
    '''
    解决 option 小写问题。
    '''
    def __init__(self,defaults=None):
        ConfigParser.ConfigParser.__init__(self,defaults=None)
    def optionxform(self, optionstr):
        return optionstr

class ConfigFileParser():
    _instance = 0
    def __init__(self):
        #self.conf = ConfigParser.ConfigParser()
        self.conf = MyConf()

    def getValue(self, section, option):
        """
		获取指定的section， 指定的option的值
		不存在则返回空
		"""
        value = ""
        configMutex.acquire()

        self.conf.read(configPath)

        if self.conf.has_section(section):
            if self.conf.has_option(section, option):
                value = self.conf.get(section, option)
        configMutex.release()
        return value

    def addSection(self, new_section, option=None, value=None):
        """
		写入指定 section, 增加新 option 的值
		添加成功 返回    True
        失败     返回    False
		"""
        ret = False
        configMutex.acquire()
        self.conf.read(configPath)
        if not self.conf.has_section(new_section):
            self.conf.add_section(new_section)
            #判断键值和数据是否有效
            if option and value:
                self.conf.set(new_section, option, value)
            self.conf.write(open(configPath,"w"))

            ret = True
        configMutex.release()
        return ret

    def addOption(self, section, option, value):
        """
		在指定的section, 增加新option的值
		添加成功 返回    True
        失败     返回    False
		"""
        ret = False
        configMutex.acquire()
        self.conf.read(configPath)
        if self.conf.has_section(section):
            if not self.conf.has_option(section, option):
                self.conf.set(section, option, value)
                self.conf.write(open(configPath,"w"))
                ret = True
        configMutex.release()
        return ret

    #################################
    #   has_section
    #   不存在返回  False
    #   存在返回   True
    #################################
    def has_section(self, section):
        """是否存在指定的section"""
        ret = False
        configMutex.acquire()
        self.conf.read(configPath)
        if self.conf.has_section(section):
            ret = True
        configMutex.release()
        return ret
    #################################
    #   has_option
    #   不存在返回  False
    #   存在返回   True
    #################################
    def has_option(self, section, option):
        """是否存在指定的option"""
        ret = False
        configMutex.acquire()
        self.conf.read(configPath)
        if self.conf.has_section(section):
            if self.conf.has_option(section, option):
                ret = True
        configMutex.release()
        return ret
    #################################
    #   options
    #   返回列表  []
    #################################
    def options(self, section):
        """返回所有的option"""
        configMutex.acquire()
        self.conf.read(configPath)
        ret =self.conf.options(section)
        configMutex.release()
        return ret
    #################################
    #   sections
    #   返回列表  []
    #################################
    def sections(self):
        """返回所有的section"""
        configMutex.acquire()
        self.conf.read(configPath)
        ret = self.conf.sections()
        configMutex.release()
        return ret


    def changeSectionValue(self, section, option, value):
        """
        更新指定section, option的值
        """
        ret = False
        configMutex.acquire()
        self.conf.read(configPath)

        if self.conf.has_section(section):
            if self.conf.has_option(section, option):
                self.conf.set(section, option, value)
                self.conf.write(open(configPath,"w"))
                ret = True
        configMutex.release()
        return ret

    #============================= 删 除  ============================#

    def remove_section(self, section):
        """删除指定的section"""
        ret = False
        configMutex.acquire()
        self.conf.read(configPath)
        if self.conf.has_section(section):
            self.conf.remove_section(section)
            self.conf.write(open(configPath,"w"))
            ret = True
        configMutex.release()
        return ret

    def remove_option(self, section, option):
        """删除指定的option"""
        ret = False
        configMutex.acquire()
        self.conf.read(configPath)
        if self.conf.has_section(section):
            if self.conf.has_option(section, option):
                self.conf.remove_option(section, option)
                self.conf.write(open(configPath,"w"))
                ret = True
        configMutex.release()
        return ret

    def addOrUpdateValue(self, section, option, value):
        section = str(section)
        option = str(option)
        value = str(value)
        if self.has_section(section):
            if self.has_option(section, option):
                self.changeSectionValue(section, option, value)
            else:
                self.addOption(section, option, value)
        else:
            self.addSection(section, option, value)

def get_config_info(_configPath = "C:\\config.ini",_section = "Config"):
    '''
    获取 配置信息
    返回类型 字典 {}
    '''
    global configPath 
    configPath = _configPath
    assert  isinstance(configPath, str), "configPath type must is str"
    if False == os.path.isfile(configPath):# 如果文件不存在
        raise  Exception("file" + configPath + " not exists ")

    confDic={}
    conf = ConfigFileParser()
    list_sections = conf.sections()
    if  _section not in  list_sections :   # 如果没有 _section 
        #return {}
        raise  Exception( _section + " not exists ")

    list_options = conf.options(_section)
    for key in list_options:
        value = conf.getValue(_section,key)
        confDic[key] = value
    return confDic

def change_file_attributes(path):
    import win32api,win32con
    import platform
    if platform.system() == "Windows":   # windows 平台
        fileAttributes =  win32api.GetFileAttributes(path)  # 读取文件属性
        #if fileAttributes & win32con.FILE_ATTRIBUTE_READONLY == win32con.FILE_ATTRIBUTE_READONLY :  # 判断文件是只读
        #    win32api.SetFileAttributes(path,win32con.FILE_ATTRIBUTE_NORMAL)        # 设置 可写 不隐藏
        if fileAttributes != win32con.FILE_ATTRIBUTE_NORMAL :  # 
            win32api.SetFileAttributes(path,win32con.FILE_ATTRIBUTE_NORMAL)        # 设置 可写 不隐藏
    elif platform.system() == "Linux":   # Linux 平台
        pass     # 待补充
    else:
        print "Warrning"  # 平台不支持

def change_config_info(key,value,_configPath = "C:\\config.ini",_section = "Config"):
    '''
    key :  修改的键
    value: 修改键值
    return :
        成功: True
        失败: False
    '''
    global configPath 
    configPath = _configPath
    assert  isinstance(configPath, str), "configPath type must is str"
    if False == os.path.isfile(configPath):# 如果文件不存在
        raise  Exception("file " + configPath + "not exists ")
    assert  isinstance(key, str), "key type must is str"
    
    change_file_attributes(configPath) # 修改文件属性可写

    conf = ConfigFileParser()
    ret =  conf.changeSectionValue(_section,key,value)
    return ret


def change_config_info_json(_info):
    '''
    _info{
        key :  修改的键
        value: 修改键值
    }
    return :
        成功: True
        失败: False
    '''

    info = json.loads(_info)    
    #assert  isinstance(info, dict), "info must be dict"
    #assert  isinstance(info, str), "info must be dict"

    key = info["key"]
    value = info["value"]

    global configPath 
    configPath = info["configPath"]
    assert  isinstance(configPath, unicode), "configPath type must is str"
    if False == os.path.isfile(configPath):# 如果文件不存在
        raise  Exception("file " + configPath + "not exists ")
    #assert  isinstance(key, str), "key type must is str"
    conf = ConfigFileParser()
    return conf.changeSectionValue("Config",key,value)

def add_config_info(key,value,_configPath = "C:\\config.ini",_section = "Config"):
    '''
    key : 新增加的键
    value: 新增加的键值
    return :
        成功: True
        失败: False
    '''
    global configPath 
    configPath = _configPath
    assert  isinstance(configPath, str), "configPath type must is str"
    if False == os.path.isfile(configPath):
        raise  Exception(configPath + " not exists ")

    assert  isinstance(key, str), "key type must is str"
    conf = ConfigFileParser()
    return conf.addOption(_section,key,value)

def del_config_info(key,_configPath = "C:\\config.ini",_section = "Config"):
    '''
    key         : 要删除的key
    _configPath : 配置文件路径
    return
         成功： True
         失败： False
    '''
    global configPath 
    configPath = _configPath
    assert  isinstance(configPath, str), "configPath type must is str"
    if False == os.path.isfile(configPath):  # 如果文件不存在
        raise  Exception(configPath + " not exists ")

    assert  isinstance(key, str), "key type must is str"
    conf = ConfigFileParser()
    return conf.remove_option(_section,key)

def add_section(_section, _configPath = "C:\\config.ini"):
    '''
    _section    :  
    _configPath : 配置文件路径
    return
         成功： True
         失败： False
    '''
    global configPath 
    global configPath 
    assert  isinstance(_configPath, str), "configPath type must is str"
    configPath = _configPath
    if False == os.path.isfile(configPath):  # 如果文件不存在
        raise  Exception(configPath + " not exists ")
    
    assert  isinstance(_section, str), "_section type must is str"
    conf = ConfigFileParser()
    return conf.addSection(_section)

def del_section(_section, _configPath = "C:\\config.ini"):
    '''
    _section    :  
    _configPath : 配置文件路径
    return
         成功： True
         失败： False
    '''
    
    return None

    #global configPath 
    #global configPath 
    #assert  isinstance(_configPath, str), "configPath type must is str"
    #configPath = _configPath
    #if False == os.path.isfile(configPath):  # 如果文件不存在
    #    raise  Exception(configPath + " not exists ")
    #
    #assert  isinstance(_section, str), "_section type must is str"
    #conf = ConfigFileParser()
    #return conf.remove_section(_section)



#################################################
##  单元测试
#################################################
#if __name__ == "__main__":
#    try:
#        # print get_config_info("abvsadf")
#        print get_config_info("C:/config.ini")
#        #print get_config_info("C:/tmp/config.ini")
#        # test
#        #print change_config_info("Model","abcd","C:\\config.ini")
#        print "----"
#        ret =  change_config_info("Model","abcd123","C:/config.ini")
#        print "aa :", ret
#        ret =  change_config_info("Model","abcd123","C:/tmp/config.ini")
#        print "----"
#        print "bb :", ret
#        # print change_config_info("Model",123)
#        # print change_config_info("Modeldaf","abcd")
#        # print change_config_info("Modeldaf",123)
#        # print change_config_info([124],123)
#        # print add_config_info("mmmm","ccc")
#        # print del_config_info("mmmm")
#    except Exception as e:
#        print e.message


